#ifndef GTL_COMPILER_SPECIFIC_HEADER_GUARD
#define GTL_COMPILER_SPECIFIC_HEADER_GUARD

template < typename Y, int T >
class GTL__SealedBase
{
protected:
  GTL__SealedBase()
  {
  }
};

///************************************************************************/
///* Global                                                               */
///************************************************************************/
#if __cplusplus > 199711L
  #define GTL_IS_CPP_0X
#endif

#define GTL_STRINGIFY2( x ) #x 
#define GTL_STRINGIFY( x ) GTL_STRINGIFY2(x)

///************************************************************************/
///* Microsoft Visual C++                                                 */
///************************************************************************/

#ifdef _MSC_VER
	#pragma warning ( disable: 4201 ) /// Disable nameless structs/unions being reported as warnings
	#pragma warning ( disable: 4100 ) /// Disable named but not used function parameters being reported as warnings

  #define GTL_COMPILER_VISUAL_STUDIO 1
  #define GTL_COMPILER_STRING "vs"

  #ifdef WIN32
    #define GTL_OS_WINDOWS
  #endif

  #ifdef _M_X64
    #define GTL_64_BIT_COMPILER
  #endif

  #define GTL_COMPILER_TYPE_PACKING_ENABLED 1

  #ifdef _CPPRTTI /// RTTI enabled
  #define GTL_COMPILER_RTTI_ENABLED 1
  #endif

  #ifdef _CPPUNWIND /// exceptions enabled
  #define GTL_COMPILER_EXCEPTIONS_ENABLED 1
  #endif

  #if _MSC_VER >= 1500
  #define GTL_COMPILER_SUPPORTS_BASIC_CPP0X 1
  #endif

  #ifdef _DLL
    #define GTL_COMPILER_BUILDING_DLL 1
    #define GTL_DLLIMPORT __declspec (dllexport)
  #else
    #define GTL_DLLIMPORT __declspec (dllimport)
  #endif

  #define GTL_BEFORE_TYPE_DECL_ALIGN(m) __declspec(align(m))
  #define GTL_BEFORE_TYPE_DECL_ALIGN_BEST __declspec(align(16)) /// Visual Studio can't figure out the best alignment

  #define GTL_AFTER_TYPE_DECL_ALIGN(m)
  #define GTL_AFTER_TYPE_DECL_ALIGN_BEST

  #define GTL_BEFORE_FUNCTION_DECL_NOINLINE __declspec(noinline)
  #define GTL_AFTER_FUNCTION_DECL_NOINLINE

  #define GTL_BEFORE_FUNCTION_DECL_FORCE_INLINE __forceinline
  #define GTL_AFTER_FUNCTION_DECL_FORCE_INLINE

  #define GTL_BEFORE_TYPE_DECL_PACKED __pragma(pack(push,1))
  #define GTL_AFTER_TYPE_DECL_PACKED __pragma(pack(pop))
  #define GTL_VARIABLE_PACKED

  #define GTL_RESTRICT_POINTER __restrict
  #define GTL_BEFORE_FUNCTION_DECL_RESTRICT __declspec(restrict)
  #define GTL_AFTER_FUNCTION_DECL_RESTRICT

  #define GTL_THREAD_LOCAL __declspec(thread)

  #define GTL_COUNTER __COUNTER__

  #ifdef GTL_64_BIT_COMPILER
    #define GTL_SOFT_BREAKPOINT __debugbreak()
  #else
    #define GTL_SOFT_BREAKPOINT __asm int 3;
  #endif

  #define GTL_interface class __declspec(novtable)

  #define GTL_sealed_class private virtual SealedBase<int,__COUNTER__>
#endif

///************************************************************************/
///* G++                                                                  */
///************************************************************************/

#ifdef __GNUC__
  
  #define GTL_COMPILER_GCC 1
  #define GTL_COMPILER_STRING "gcc"

  #define GTL_COMPILER_TYPE_PACKING_ENABLED 1

  #ifdef __GXX_RTTI
  #define GTL_COMPILER_RTTI_ENABLED 1
  #endif
  
  /// #define GTL_COMPILER_EXCEPTIONS_ENABLED 1 ??

  #ifdef __unix__
  #define GTL_OS_UNIX
  #endif

  #ifdef __EXCEPTIONS
  #define GTL_COMPILER_EXCEPTIONS_ENABLED 1
  #endif

  #ifdef __GXX_EXPERIMENTAL_CXX0X__
  #define GTL_COMPILER_SUPPORTS_BASIC_CPP0X 1
  #endif

  #define GTL_DLLEXPORT __attribute__ ((visibility("default")))
  #define GTL_DLLIMPORT extern

  #define GTL_BEFORE_TYPE_DECL_ALIGN(m)
  #define GTL_AFTER_TYPE_DECL_ALIGN(m) __attribute__ ((aligned (m)));
  
  #define GTL_BEFORE_TYPE_DECL_ALIGN_BEST
  #define GTL_AFTER_TYPE_DECL_ALIGN_BEST __attribute__ ((aligned));

  #define GTL_BEFORE_FUNCTION_DECL_NOINLINE
  #define GTL_AFTER_FUNCTION_DECL_NOINLINE __attribute__ ((noinline));

  #define GTL_BEFORE_FUNCTION_DECL_FORCE_INLINE inline
  #define GTL_AFTER_FUNCTION_DECL_FORCE_INLINE __attribute__ ((always_inline))

  #define GTL_BEFORE_TYPE_DECL_PACKED
  #define GTL_AFTER_TYPE_DECL_PACKED __attribute__ ((packed))
  #define GTL_VARIABLE_PACKED

  #define GTL_RESTRICT_POINTER __restrict__
  #define GTL_BEFORE_FUNCTION_DECL_RESTRICT
  #define GTL_AFTER_FUNCTION_DECL_RESTRICT __restrict__

  #define GTL_THREAD_LOCAL __thread

  #define GTL_COUNTER __COUNTER__

  #define GTL_SOFT_BREAKPOINT asm("int $3");

  #define GTL_interface class

  #define GTL_sealed_class private virtual SealedBase<int,__COUNTER__>
#endif

///************************************************************************/
///* POSIX but not G++                                                    */
///************************************************************************/

#if !defined(GTL_COMPILER_GCC) && defined(POSIX) /// non GCC posix-compliant compiler
  #define GTL_COMPILER_POSIX_COMPLIANT 1
  #define GTL_COMPILER_STRING "posix_compliant"

  #define GTL_SOFT_BREAKPOINT __asm__( "int $0x3;")

  #define GTL_sealed_class private virtual SealedBase<int,__COUNTER__>
#endif

///************************************************************************/
///* ARM compiler                                                         */
///************************************************************************/

#if !defined(GTL_COMPILER_GCC) && defined(__arm)
/// the retarted mwccarm compiler
  #define GTL_COMPILER_ARM 1
  #define GTL_COMPILER_STRING "arm"

  #define GTL_RESTRICT_POINTER __restrict

  #define GTL_BEFORE_TYPE_DECL_ALIGN(m)
  #define GTL_BEFORE_TYPE_DECL_ALIGN_BEST

  #define GTL_AFTER_TYPE_DECL_ALIGN(m) __attribute__((aligned(m)))
  #define GTL_AFTER_TYPE_DECL_ALIGN_BEST __attribute__((aligned(16)))

  #define GTL_BEFORE_FUNCTION_DECL_NOINLINE __declspec(noinline)
  #define GTL_AFTER_FUNCTION_DECL_NOINLINE

  #define GTL_BEFORE_FUNCTION_DECL_FORCE_INLINE __forceinline
  #define GTL_AFTER_FUNCTION_DECL_FORCE_INLINE

  #define GTL_BEFORE_TYPE_DECL_PACKED DontPackClasses_PackTheirFields
  #define GTL_AFTER_TYPE_DECL_PACKED
  #define GTL_VARIABLE_PACKED __packed

  #define GTL_RESTRICT_POINTER __restrict
  #define GTL_BEFORE_FUNCTION_DECL_RESTRICT __restrict
  #define GTL_AFTER_FUNCTION_DECL_RESTRICT

  #define GTL_THREAD_LOCAL __declspec(thread)

  #define GTL_COUNTER __COUNTER__

  #define GTL_SOFT_BREAKPOINT __breakpoint(0)

  #define GTL_interface class __declspec(novtable)

  #define GTL_sealed_class private virtual SealedBase<int,__COUNTER__>
#endif

///************************************************************************/
///* Apple G++                                                            */
///************************************************************************/

#if defined(GTL_COMPILER_GCC) && defined(__APPLE__)
  #define GTL_COMPILER_IOS 1

  #define GTL_sealed_class(x) private virtual SealedBase<x,0>
#endif

///************************************************************************/
///* OS Macros                                                            */
///************************************************************************/

#ifdef WIN32
#define GTL_COMPILER_TARGET_WINDOWS 1
#endif

#ifdef WIN64
#define GTL_COMPILER_TARGET_WINDOWS64 1
#endif

#ifndef __APPLE__
#include "external/pstdint.h"
#endif

///************************************************************************/
///* Other compiler-related macros                                        */
///************************************************************************/

#define EA_COMPILER_HAS_INTTYPES

#endif 